<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      // 如果是对象/数组，返回一个空的对象/数组，
      // 都不是的话直接返回原对象
      // 判断返回的对象和原有对象是否相同就可以知道是否需要继续深拷贝
      // 处理其他的数据类型的话就在这里加判断
      function getEmpty(o) {
        if (Object.prototype.toString.call(o) === "[object Object]") {
          return {};
        }
        if (Object.prototype.toString.call(o) === "[object Array]") {
          return [];
        }
        return o;
      }

      function deepCopyBFS(origin) {
        let queue = [];
        let map = new Map(); // 记录出现过的对象，用于处理环

        let target = getEmpty(origin);
        if (target !== origin) {
          //说明origin是一个对象或者数组，需要拷贝子代
          queue.push([origin, target]);
          map.set(origin, target);
        }

        while (queue.length) {
          let [ori, tar] = queue.shift(); //出队
          for (let key in ori) {
            // 处理环状
            if (map.get(ori[key])) {
              tar[key] = map.get(ori[key]);
              continue;
            }

            tar[key] = getEmpty(ori[key]);
            if (tar[key] !== ori[key]) {
              queue.push([ori[key], tar[key]]);
              map.set(ori[key], tar[key]);
            }
          }
        }

        return target;
      }

      let arr = {
        name: "gmx",
        age: 23,
        say: ["hello", "hi"],
      };
      let newarr = deepCopyBFS(arr);
      arr.name = "zzq";
      console.log(arr);
      console.log(newarr);



      function deepCopyDFS(origin) {
        let stack = [];
        let map = new Map(); // 记录出现过的对象，用于处理环

        let target = getEmpty(origin);
        if (target !== origin) {
          stack.push([origin, target]);
          map.set(origin, target);
        }

        while (stack.length) {
          let [ori, tar] = stack.pop();
          for (let key in ori) {
            // 处理环状
            if (map.get(ori[key])) {
              tar[key] = map.get(ori[key]);
              continue;
            }

            tar[key] = getEmpty(ori[key]);
            if (tar[key] !== ori[key]) {
              stack.push([ori[key], tar[key]]);
              map.set(ori[key], tar[key]);
            }
          }
        }

        return target;
      }
    </script>
  </body>
</html>
